"""
本文件的职责:
    - contain the application factory, 
    - tell Python that the src directory should be treated as a package.
"""
import os
import logging

from flask import Flask
from flask import request
from flask import render_template
from flask_sqlalchemy import SQLAlchemy
from logging.handlers import RotatingFileHandler
from flask_login import LoginManager

basedir = os.path.abspath(os.path.dirname(__file__))

db = SQLAlchemy()
login_manager = LoginManager()

def create_app(config_name=None):
    """
    Flask自动检测create_app或make_app名称的工厂方法.
    """
    app = Flask(__name__, instance_relative_config=True)

    try:
        os.makedirs(app.instance_path)
    except OSError as e:
        print(str(e))

    logger = logging.getLogger("app")
    logger.setLevel(level=logging.DEBUG)
    formatter = logging.Formatter('%(asctime)s %(filename)s:%(lineno)d %(levelname)s %(message)s')

    rotate_handler = RotatingFileHandler(os.path.join(app.instance_path, "log.txt"), maxBytes=100 * 1024 * 1024, backupCount=30)
    rotate_handler.setLevel(logging.DEBUG)
    rotate_handler.setFormatter(formatter)
    logger.addHandler(rotate_handler)

    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.DEBUG)
    console_handler.setFormatter(formatter)
    logger.addHandler(console_handler)


    if config_name is None:
        config_name = os.environ.get('FLASK_DEVOPS_ENV') or 'development'

    logger.info(f'Module {__name__} is starting, config is {config_name}.')
    
    from .config import config
    app.config.from_object(config[config_name])
    config[config_name].init_app(app)
    


    db.init_app(app)




    @app.errorhandler(404)
    def page_not_found_error(error):
        # 这里可以记录错误日志，通过error参数获取错误信息
        # 你可以将用户重定向到一个错误页面，或者返回一个JSON错误响应
        full_url = request.url
        logger.error(f'Requested url {full_url}  {str(error)}')
        
        return {'errcode': 404, 'errmsg': str(error)}, 404


    @app.errorhandler(500)
    def internal_error(error):
        # 这里可以记录错误日志，通过error参数获取错误信息
        # 你可以将用户重定向到一个错误页面，或者返回一个JSON错误响应
        full_url = request.url
        logger.error(f'Requested url {full_url}  {str(error)}')
        
        return {'errcode': 500, 'errmsg': str(error)}, 500


    from .api import api as api_blueprint
    app.register_blueprint(api_blueprint, url_prefix='/api/v1')

    
    return app
